import { Router } from 'vue-router'
import NProgress from 'nprogress'

import store from '@/store'
import { storage } from '@/utils/storage'
import { ACCESS_TOKEN } from '@/store/constantKeys'

// nprogress bar style
import 'nprogress/css/nprogress.css'
import router from '@/router/index'

enum constantEnum {
  LOGIN = 'Login',
  REDIRECT = 'Redirect'
}

const DEFAULT_PATH = '/dashboard'
const LOGIN_PATH = '/login'
const whiteList = ['Login', '404', 'Dashboard', 'AsyncPathIndex', 'AsyncPathIndex-index']

function setAsyncRoute({ to, next, hasRoute }) {
  // 获取动态路由列表
  store.dispatch('asyncRouter/generateRoutes').then(asyncRoutes => {
    asyncRoutes.forEach(route => router.addRoute(route))

    if (whiteList.includes(to.name)) return

    if (!hasRoute) {
      next({ ...to, replace: true })
    }
  }).catch(() => next({ path: DEFAULT_PATH }))
}

export function createRouterGuards (router: Router) {
  router.beforeEach((to, from, next) => {
    // start nprogress bar
    NProgress.start()

    const TOKEN = storage.get(ACCESS_TOKEN)
    if (TOKEN) {
      // have user token
      if (to.name === constantEnum.LOGIN) {
        // current path is login page
        next({ path: DEFAULT_PATH })
        NProgress.done()
      } else {
        const hasRoute = router.hasRoute(to.name!)

        setAsyncRoute({ to, next, hasRoute })

        if (whiteList.includes(to.name as string) || hasRoute) {
          // in white
          next()
        }
      }
    } else {
      // not login
      if (whiteList.includes(to.name as string)) {
        // in white
        next()
      } else {
        // redirect to login page
        next({
          path: LOGIN_PATH,
          query: { redirect: to.fullPath },
          replace: true
        })
        NProgress.done()
      }
    }
  })

  router.afterEach((to) => {
    document.title = (to?.meta?.title as string) || document.title

    // if (isNavigationFailure(failure)) {
    //   console.log('failed navigation', failure)
    // }

    // set need to cache component name
    const keepAliveComponents = store.getters['asyncRouter/keepAliveComponents']
    const currentComponentName = to.matched.find((item) => item.name === to.name)?.components?.default.name
    if (currentComponentName && !keepAliveComponents.includes(currentComponentName) && to.meta?.keepAlive) {
      keepAliveComponents.push(currentComponentName)
    } else if (!to.meta?.keepAlive || to.name === constantEnum.REDIRECT) {
      const index = keepAliveComponents.findIndex((name: string) => name === currentComponentName)
      if (index !== -1) {
        keepAliveComponents.splice(index, 1)
      }
    }

    store.commit('asyncRouter/setKeepAliveComponents', keepAliveComponents)
    NProgress.done()
  })

  router.onError((error) => {
    console.log(error, '路由错误')
  })
}
